package com.example.experiment_2java.interceptor;


import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.experiment_2java.annotation.Role;
import com.example.experiment_2java.annotation.RoleAuthorization;
import com.example.experiment_2java.util.result.DataResult;
import com.example.experiment_2java.util.result.code.Code;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import static com.example.experiment_2java.util.JWTUtils.verify;

/**
 * @Description: JWT拦截器
 * @Author：Jukomu
 * @Package：org.csu.mypetstore.interceptor
 * @Project：MyPetStore-SSM
 * @name：JWTInterceptor
 * @Date：2024/4/1 1:48
 * @Filename：JWTInterceptor
 */
public class JWTInterceptor implements HandlerInterceptor {
    private final Logger logger = LoggerFactory.getLogger(JWTInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        RoleAuthorization roleAuthorization = null;
        if (handler instanceof HandlerMethod handlerMethod) {
            roleAuthorization = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), RoleAuthorization.class);
        }
        // 处理不是 HandlerMethod 类型的情况
        if (roleAuthorization == null) {
            logger.info("Role authorization:common");
            return true;
        }

        // 从 URL 参数中获取令牌
        String token = request.getParameter("token");
        if (token == null || token.isEmpty()) {
            returnJsonResponse(response, DataResult.errByErrCode(Code.LOGIN_OUT));
            return false;
        }

        // 根据角色进行权限校验
        if (roleAuthorization.value() == Role.MANAGER) {
            try {
                DecodedJWT decodedJWT = verify(token);
                if (decodedJWT.getClaim("role").asString().equals("MANAGER")) {
                    // token有效且权限为管理员
                    logger.info("Role authorization:{manager:" + decodedJWT.getClaim("username").asString() + "}");
                    return true;
                } else {
                    // token有效但权限不是管理员
                    returnJsonResponse(response, DataResult.errByErrCode(Code.PERMISSION_DENY));
                    return false;
                }
            } catch (JWTVerificationException e) {
                // token无效
                returnJsonResponse(response, DataResult.errByErrCode(Code.LOGIN_OUT));
                return false;
            }
        }

        if (roleAuthorization.value() == Role.USER) {
            try {
                DecodedJWT decodedJWT = verify(token);
                // 只要令牌有效都满足USER权限
                return true;
            } catch (JWTVerificationException e) {
                // token无效
                returnJsonResponse(response, DataResult.errByErrCode(Code.LOGIN_OUT));
                return false;
            }
        }
        return false;
    }

    /**
     * 直接写入 JSON 响应
     */
    private void returnJsonResponse(HttpServletResponse response, DataResult<?> result) throws Exception {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(200);
        response.getWriter().write(new ObjectMapper().writeValueAsString(result));
        response.getWriter().flush();
    }
}
